#ifndef _NES_CONFIG_H
#define _NES_CONFIG_H

//////////////////////////////////////////////////////////////////////////
// iNES
enum
{
  VMirror             = 1 << 0,
  VRamExist           = 1 << 1,
  TrainerExist        = 1 << 2,
  FourScreenExist     = 1 << 3,
};

#define MAPPER_NO     4

#pragma pack(push, 1)
struct NesHeader
{
  u8  sig[4];
  u8  prg_count;
  u8  chr_count;
  u8  control1;
  u8  control2;
  u8  reserved[8];
};
#pragma pack(pop)
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// PPU
#define BG_TILES_COUNT          256

#define FRAME_RATE              60

// PPU reg 2000
#define PPU_NAMETABLE           0x03
#define PPU_VRAM_INC_STEP       0x04
#define PPU_SP_PTN_TBL          0x08
#define PPU_NAME_PTN_TBL        0x10
#define PPU_SP_SIZE             0x20

// PPU reg 2001
#define PPU_SHOW_BG             0x08
#define PPU_SHOW_SP             0x10

// PPU reg 2002
#define PPU_MAX_SPRITE          0x20
#define PPU_SPRITE_0_HIT        0x40
#define PPU_VBLANK_FLAG         0x80

// Sprite
#define MAX_SPRITE_NUM          64
#define SP_ATTRIB_FLIP_X        0x40
#define SP_ATTRIB_FLIP_Y        0x80

// Sprite information
#pragma pack(push, 1)
struct SpriteInfo
{
  u8  y;
  u8  tile;
  u8  attrib;
  u8  x;
};
#pragma pack(pop)
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// cpu
// 6502 status flags
#define C_FLAG                          0001        // 0: Carry flag
#define Z_FLAG                          0x02        // 1: Zero flag
#define I_FLAG                          0x04        // 2: interrupt enable/disable flag
#define D_FLAG                          0x08        // 3: decimal mode status flag
#define B_FLAG                          0x10        // 4: set when a software interrupt (BRK instruction) is executed.
#define R_FLAG                          0x20        // 5: reserved (Always 1)
#define V_FLAG                          0x40        // 6: Overflow flag
#define N_FLAG                          0x80        // 7: Sign flag

// interrupt vectors
#define NMI_VECTOR                      0xFFFA
#define RESET_VECTOR                    0xFFFC
#define IRQ_VECTOR                      0xFFFE

// Prg Bank count
#define PRG_BANK_COUNT                  4
#define PRG_BANK_SIZE                   8*1024
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// video memory
#define FRAME_START                     0
#define FRAME_END                       240
#define SCANLINES_VBLANK_START          243
#define SCANLINES_VBLANK_END            262

#define CYCLES_PER_FRAME                29828
#define CYCLES_PER_SCANLINE             (CYCLES_PER_FRAME/SCANLINES_VBLANK_END)

#define SCREEN_W                        256
#define SCREEN_H                        240

// rom releated
#define PRGPageSize                     16*1024
#define CHRPageSize                     8 *1024

#define PATTERN_W                       128
#define PATTERN_H                       256

#define TILES_COUNT_IN_PTN_TBL          512

#define TILE_COUNT_W                    32
#define TILE_COUNT_H                    30
#define NAME_TBL_W                      (TILE_COUNT_W*8)
#define NAME_TBL_H                      (TILE_COUNT_H*8)

// 8*8 tile info
typedef u16 PPUTile[8][8];
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// Joypad
#define JOYPAD_A                        (1<<0)
#define JOYPAD_B                        (1<<1)
#define JOYPAD_SELECT                   (1<<2)
#define JOYPAD_START                    (1<<3)
#define JOYPAD_UP                       (1<<4)
#define JOYPAD_DOWN                     (1<<5)
#define JOYPAD_LEFT                     (1<<6)
#define JOYPAD_RIGHT                    (1<<7)

#endif  // _NES_CONFIG_H
